package com.cnpc.rightslogan.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Create by shaojie on 2019/8/7
 * 在前后端分离的情况下，我们登录成功了可能需要向前端返回用户的个人信息，而不是直接进行跳转。
 * 登录失败也是同样的道理。这里涉及到了 Spring Security 中的两个接口AuthenticationSuccessHandler和AuthenticationFailureHandler。
 * 自定义这两个接口的实现，并进行相应的配置就可以了。 当然框架是有默认的实现类的，我们可以继承这个实现类再来自定义自己的业务：
 * <p>
 * 这里有个细节需要注意：
 * <p>
 * principal 中有个权限数组集合authorities，里面的权限值是：ROLE_admin，而自定义的安全认证配置中配置的是：admin，
 * 所以ROLE_前缀是框架自己加的，后期取出权限集合的时候需要注意这个细节，以取决于判断是否有权限是使用字符串的包含关系还是等值关系。
 * <p>
 * 成功登录处理类
 */
@Slf4j
@Component("myAuthenctiationSuccessHandler")
public class MyAuthenctiationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response, Authentication authentication) throws IOException, ServletException {

        logger.info("登录成功");
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(objectMapper.writeValueAsString(authentication));
    }

    /**
     * 成功登录之后，通过 response 返回一个 JSON 字符串回去。这个方法中的第三个参数Authentication，它里面包含了登录后的用户信息（UserDetails），Session 的信息，登录信息等。
     *
     * 登录成功之后的响应JSON：
     *
     *  {
     *     "authorities": [
     *         {
     *             "authority": "ROLE_admin"
     *         }
     *     ],
     *     "details": {
     *         "remoteAddress": "127.0.0.1",
     *         "sessionId": "8BFA4F61A7CEA774C00F616AAE8C307C"
     *     },
     *     "authenticated": true,
     *     "principal": {
     *         "password": null,
     *         "username": "admin",
     *         "authorities": [
     *             {
     *                 "authority": "ROLE_admin"
     *             }
     *         ],
     *         "accountNonExpired": true,
     *         "accountNonLocked": true,
     *         "credentialsNonExpired": true,
     *         "enabled": true
     *     },
     *     "credentials": null,
     *     "name": "admin"
     * }
     */
}